// 蜂窝蜜造平台生成代码，此文件只生成一次，不需要添加到 .beeignore

package com.fowo.api.service.impl;

import com.fowo.api.entity.Requisition;
import com.fowo.api.inventory.model.*;
import com.fowo.api.inventory.model.form.InventoryOutboundFormVo;
import com.fowo.api.inventory.model.form.InventoryStorageFormVo;
import com.fowo.api.inventory.service.InventoryBusinessService;
import com.fowo.api.model.requisition.RequisitionVo;
import com.fowo.api.model.requisition.product.RequisitionProductItemVo;
import com.fowo.api.sys.annotation.DataActivity;
import com.fowo.api.sys.entity.enums.SysDataActivityAction;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 调拨单 服务实现类
 */
@Service
public class RequisitionServiceImpl extends RequisitionBaseServiceImpl {
    @Resource
    private InventoryBusinessService inventoryBusinessService;

    /**
     * 提交并调拨
     */
//    @Override
//    public void submitTransfer(Long id) throws Exception {
//        if (requisitionConfirmationTransferAction == null) {
//            throw new Exception("此操作当前不可用");
//        }
//        requisitionConfirmationTransferAction.run(id);
//    }
    /**
     * 提交
     */
    @DataActivity(
            action = SysDataActivityAction.Other,
            message = "%s执行了提交操作"
    )
    @Override
    public void tjcommit(List<Long> ids) throws Exception {
        if (requisitionReferAction == null) {
            throw new Exception("此操作当前不可用");
        }
        for(Long id : ids){
            requisitionReferAction.run(id);
        }
    }

    /**
     * 确认调拨
     */
    @DataActivity(
            action = SysDataActivityAction.Other,
            message = "%s执行了确认调拨操作"
    )
    @Override
    public void notarize(List<Long> ids) throws Exception {
        if (requisitionConfirmationTransferAction == null) {
            throw new Exception("此操作当前不可用");
        }
        for(Long id : ids){
            requisitionConfirmationTransferAction.run(id);
        }
    }

    /**
     * 提交并调拨
     */
    @DataActivity(
            action = SysDataActivityAction.Other,
            message = "%s执行了提交并调拨操作"
    )
    @Override
    public void commitAndRqt(List<Long> ids) throws Exception {
        if (requisitionSubmitTransferAction == null) {
            throw new Exception("此操作当前不可用");
        }
        for(Long id : ids){
            requisitionSubmitTransferAction.run(id);
        }
    }

    /**
     * 全部到货
     */
    @DataActivity(
            action = SysDataActivityAction.Other,
            message = "%s执行了全部到货操作"
    )
    @Override
    public void allAOG(List<Long> ids) throws Exception {
        if (requisitionConfirmReceiptAction == null) {
            throw new Exception("此操作当前不可用");
        }
        for(Long id : ids){
            requisitionConfirmReceiptAction.run(id);
        }
    }

    /**
     * 提交
     */
    @DataActivity(
            action = SysDataActivityAction.Other,
            message = "%s执行了提交操作"
    )
    @Override
    public void present(Long id) throws Exception {
        if (requisitionReferAction == null) {
            throw new Exception("此操作当前不可用");
        }
        requisitionReferAction.run(id);
    }

    /**
     * 提交并调拨
     */
    @DataActivity(
            action = SysDataActivityAction.Other,
            message = "%s执行了提交并调拨操作"
    )
    @Override
    public void submitAndTransfer(Long id) throws Exception {
        if (requisitionSubmitTransferAction == null) {
            throw new Exception("此操作当前不可用");
        }
        requisitionSubmitTransferAction.run(id);
    }

    /**
     * 确认调拨
     */
    @DataActivity(
            action = SysDataActivityAction.Other,
            message = "%s执行了确认调拨操作"
    )
    @Override
    public void confirmationTransfers(Long id) throws Exception {
        if (requisitionConfirmationTransferAction == null) {
            throw new Exception("此操作当前不可用");
        }
        requisitionConfirmationTransferAction.run(id);
    }

    /**
     * 确认收货
     */
    @DataActivity(
            action = SysDataActivityAction.Other,
            message = "%s执行了确认收货操作"
    )
    @Override
    public void confirmReceipts(Long id) throws Exception {
        if (requisitionConfirmReceiptAction == null) {
            throw new Exception("此操作当前不可用");
        }
        requisitionConfirmReceiptAction.run(id);
    }


    /**
     * 次品出库
     */
    @DataActivity(
            action = SysDataActivityAction.Other,
            message = "%s执行了次品出库操作"
    )
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void badOut(Long id) throws Exception {
        RequisitionVo vo = getVoById(id);
        InventoryOutboundFormVo formVo = prepareBadOut(vo);
        inventoryBusinessService.outbound(formVo);

    }

    /**
     * 准备用于 次品出库 的参数
     */
    protected InventoryOutboundFormVo prepareBadOut(RequisitionVo vo)
            throws Exception {
        if (!"1".equals(vo.getStatus()) && !"0".equals(vo.getStatus()) ) {
            throw new Exception("当前单据状态不可进行此操作！");
        }
        InventoryOutboundFormVo formVo = new InventoryOutboundFormVo();
        formVo.setFrom(TargetTypeEnum.Defect);
        formVo.setFormNum(vo.getRqtSn());
        formVo.setDocumentType("调拨出库");
        if (ObjectUtils.isEmpty(vo.getLastUpdateUser())) {
            throw new Exception("关联制单人为空");
        }
        formVo.setFormOperator(vo.getLastUpdateUser().toString());
        if (ObjectUtils.isEmpty(vo.getWid())) {
            throw new Exception("仓库 为空");
        }
        formVo.setStockId(vo.getWid());
        formVo.setModel(PatternEnum.FIFO);
        for (RequisitionProductItemVo requisitionProduct : vo.getRequisitionProduct()) {
            SimpleInventoryItem inventoryItem = new SimpleInventoryItem();
            inventoryItem.setId(requisitionProduct.getProductId());
            InventoryOutboundVo outboundItem = new InventoryOutboundVo();
            outboundItem.setItem(inventoryItem);
            outboundItem.setQty(
                    String
                            .valueOf(requisitionProduct.getDefectiveRqtQuantity())
                            .equals("null")
                            ? BigDecimal.valueOf(0)
                            : BigDecimal.valueOf(requisitionProduct.getDefectiveRqtQuantity())
            );
            outboundItem.setShopId(
                    String.valueOf(requisitionProduct.getShopName()).equals("null")
                            ? null
                            : String.valueOf(requisitionProduct.getShopName())
            );
            outboundItem.setFnSku(
                    String.valueOf(requisitionProduct.getFnsku()).equals("null")
                            ? null
                            : String.valueOf(requisitionProduct.getFnsku())
            );
            Map<Long, Integer> binIds = new HashMap<>();
            binIds.put(
                    requisitionProduct.getFromBadWarehouseBin(),
                    Integer.parseInt(
                            String
                                    .valueOf(requisitionProduct.getDefectiveRqtQuantity())
                                    .equals("null")
                                    ? "0"
                                    : String.valueOf(requisitionProduct.getDefectiveRqtQuantity())
                    )
            );
            outboundItem.setBinIds(binIds);
            outboundItem.setFromBinIdsType(TargetTypeEnum.Normal);
            outboundItem.setCustomId(vo.getId());
            outboundItem.setCustomBdId(requisitionProduct.getId());
            formVo.add(outboundItem);
        }
        return formVo;
    }

    /**
     * 良品出库
     */
    @DataActivity(
            action = SysDataActivityAction.Other,
            message = "%s执行了良品出库操作"
    )
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void goodOut(Long id) throws Exception {
        RequisitionVo vo = getVoById(id);
        InventoryOutboundFormVo formVo = prepareGoodOut(vo);
        inventoryBusinessService.outbound(formVo);
    }

    /**
     * 准备用于 良品出库 的参数
     */
    protected InventoryOutboundFormVo prepareGoodOut(RequisitionVo vo)
            throws Exception {
        if (!"1".equals(vo.getStatus()) && !"0".equals(vo.getStatus()) ) {
            throw new Exception("当前单据状态不可进行此操作！");
        }
        InventoryOutboundFormVo formVo = new InventoryOutboundFormVo();
        formVo.setFrom(TargetTypeEnum.Normal);
        formVo.setFormNum(vo.getRqtSn());
        formVo.setDocumentType("调拨出库");
        if (ObjectUtils.isEmpty(vo.getLastUpdateUser())) {
            throw new Exception("关联制单人为空");
        }
        formVo.setFormOperator(vo.getLastUpdateUser().toString());
        if (ObjectUtils.isEmpty(vo.getWid())) {
            throw new Exception("仓库 为空");
        }
        formVo.setStockId(vo.getWid());
        formVo.setModel(PatternEnum.FIFO);
        for (RequisitionProductItemVo requisitionProduct : vo.getRequisitionProduct()) {
            SimpleInventoryItem inventoryItem = new SimpleInventoryItem();
            inventoryItem.setId(requisitionProduct.getProductId());
            InventoryOutboundVo outboundItem = new InventoryOutboundVo();
            outboundItem.setItem(inventoryItem);
            outboundItem.setQty(
                    String.valueOf(requisitionProduct.getAvailbleRqtNum()).equals("null")
                            ? BigDecimal.valueOf(0)
                            : BigDecimal.valueOf(requisitionProduct.getAvailbleRqtNum())
            );
            outboundItem.setShopId(
                    String.valueOf(requisitionProduct.getShopName()).equals("null")
                            ? null
                            : String.valueOf(requisitionProduct.getShopName())
            );
            outboundItem.setFnSku(
                    String.valueOf(requisitionProduct.getFnsku()).equals("null")
                            ? null
                            : String.valueOf(requisitionProduct.getFnsku())
            );
            Map<Long, Integer> binIds = new HashMap<>();
            binIds.put(
                    requisitionProduct.getFromGoodWarehouseBin(),
                    Integer.parseInt(
                            String.valueOf(requisitionProduct.getAvailbleRqtNum()).equals("null")
                                    ? "0"
                                    : String.valueOf(requisitionProduct.getAvailbleRqtNum())
                    )
            );
            outboundItem.setBinIds(binIds);
            outboundItem.setFromBinIdsType(TargetTypeEnum.Normal);
            outboundItem.setCustomId(vo.getId());
            outboundItem.setCustomBdId(requisitionProduct.getId());
            formVo.add(outboundItem);
        }
        return formVo;
    }

    /**
     * 次品入库
     */
    @DataActivity(
            action = SysDataActivityAction.Other,
            message = "%s执行了次品入库操作"
    )
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void badIn(Long id) throws Exception {
        RequisitionVo vo = getVoById(id);
        InventoryStorageFormVo formVo = prepareBadIn(vo);
        inventoryBusinessService.storage(formVo);
    }

    /**
     * 准备用于 次品入库 的参数
     */
    protected InventoryStorageFormVo prepareBadIn(RequisitionVo vo)
            throws Exception {
        if (!"1".equals(vo.getStatus()) && !"0".equals(vo.getStatus()) && !"2".equals(vo.getStatus()) ) {
            throw new Exception("当前单据状态不可进行此操作！");
        }
        InventoryStorageFormVo formVo = new InventoryStorageFormVo();
        formVo.setTo(TargetTypeEnum.Defect);
        formVo.setFormNum(vo.getRqtSn());
        formVo.setDocumentType("调拨入库");
        if (ObjectUtils.isEmpty(vo.getLastUpdateUser())) {
            throw new Exception("关联制单人为空");
        }
        formVo.setFormOperator(vo.getLastUpdateUser().toString());
        if (ObjectUtils.isEmpty(vo.getToWid())) {
            throw new Exception("仓库 为空");
        }
        formVo.setStockId(vo.getToWid());
        for (RequisitionProductItemVo requisitionProduct : vo.getRequisitionProduct()) {
            SimpleInventoryItem inventoryItem = new SimpleInventoryItem();
            inventoryItem.setId(requisitionProduct.getProductId());
            InventoryStorageVo storageItem = new InventoryStorageVo();
            storageItem.setItem(inventoryItem);
            storageItem.setQty(
                    String
                            .valueOf(requisitionProduct.getDefectiveRqtQuantity())
                            .equals("null")
                            ? BigDecimal.valueOf(0)
                            : BigDecimal.valueOf(requisitionProduct.getDefectiveRqtQuantity())
            );
            storageItem.setShopId(
                    String.valueOf(requisitionProduct.getShopName()).equals("null")
                            ? null
                            : String.valueOf(requisitionProduct.getShopName())
            );
            storageItem.setFnSku(
                    String.valueOf(requisitionProduct.getFnsku()).equals("null")
                            ? null
                            : String.valueOf(requisitionProduct.getFnsku())
            );
            Map<Long, Integer> binIds = new HashMap<>();
            binIds.put(
                    requisitionProduct.getToBadWarehouseBin(),
                    Integer.parseInt(
                            String
                                    .valueOf(requisitionProduct.getDefectiveRqtQuantity())
                                    .equals("null")
                                    ? "0"
                                    : String.valueOf(requisitionProduct.getDefectiveRqtQuantity())
                    )
            );
            storageItem.setBinIds(binIds);
            storageItem.setFromBinIdsType(TargetTypeEnum.Normal);
            storageItem.setCustomId(vo.getId());
            storageItem.setCustomBdId(requisitionProduct.getId());
            formVo.add(storageItem);
        }
        return formVo;
    }

    /**
     * 良品入库
     */
    @DataActivity(
            action = SysDataActivityAction.Other,
            message = "%s执行了良品入库操作"
    )
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void goodIn(Long id) throws Exception {
        RequisitionVo vo = getVoById(id);
        InventoryStorageFormVo formVo = prepareGoodIn(vo);
        inventoryBusinessService.storage(formVo);
    }

    /**
     * 准备用于 良品入库 的参数
     */
    protected InventoryStorageFormVo prepareGoodIn(RequisitionVo vo)
            throws Exception {
        if (!"1".equals(vo.getStatus()) && !"0".equals(vo.getStatus()) && !"2".equals(vo.getStatus()) ) {
            throw new Exception("当前单据状态不可进行此操作！");
        }
        InventoryStorageFormVo formVo = new InventoryStorageFormVo();
        formVo.setTo(TargetTypeEnum.Normal);
        formVo.setFormNum(vo.getRqtSn());
        formVo.setDocumentType("调拨入库");
        if (ObjectUtils.isEmpty(vo.getLastUpdateUser())) {
            throw new Exception("关联制单人为空");
        }
        formVo.setFormOperator(vo.getLastUpdateUser().toString());
        if (ObjectUtils.isEmpty(vo.getToWid())) {
            throw new Exception("仓库 为空");
        }
        formVo.setStockId(vo.getToWid());
        for (RequisitionProductItemVo requisitionProduct : vo.getRequisitionProduct()) {
            SimpleInventoryItem inventoryItem = new SimpleInventoryItem();
            inventoryItem.setId(requisitionProduct.getProductId());
            InventoryStorageVo storageItem = new InventoryStorageVo();
            storageItem.setItem(inventoryItem);
            storageItem.setQty(
                    String.valueOf(requisitionProduct.getAvailbleRqtNum()).equals("null")
                            ? BigDecimal.valueOf(0)
                            : BigDecimal.valueOf(requisitionProduct.getAvailbleRqtNum())
            );
            storageItem.setShopId(
                    String.valueOf(requisitionProduct.getShopName()).equals("null")
                            ? null
                            : String.valueOf(requisitionProduct.getShopName())
            );
            storageItem.setFnSku(
                    String.valueOf(requisitionProduct.getFnsku()).equals("null")
                            ? null
                            : String.valueOf(requisitionProduct.getFnsku())
            );
            Map<Long, Integer> binIds = new HashMap<>();
            binIds.put(
                    requisitionProduct.getToGoodWarehouseBin(),
                    Integer.parseInt(
                            String.valueOf(requisitionProduct.getAvailbleRqtNum()).equals("null")
                                    ? "0"
                                    : String.valueOf(requisitionProduct.getAvailbleRqtNum())
                    )
            );
            storageItem.setBinIds(binIds);
            storageItem.setFromBinIdsType(TargetTypeEnum.Normal);
            storageItem.setCustomId(vo.getId());
            storageItem.setCustomBdId(requisitionProduct.getId());
            formVo.add(storageItem);
        }
        return formVo;
    }

    /**
     * 列表上的撤销
     */
    @DataActivity(
            action = SysDataActivityAction.Other,
            message = "%s执行了撤销操作"
    )
    @Override
    public void revocationOrder(Long id) throws Exception {
        if (requisitionRevocationAction == null) {
            throw new Exception("此操作当前不可用");
        }
        requisitionRevocationAction.run(id);
    }
}
